package solutions.ferpa.ztest.util;

import br.com.telescope.adsrt.dom.DomDouble;
import br.com.telescope.adsrt.lib.AdsException;
import br.com.telescope.adsrt.lib.AdsUtil;
import br.com.telescope.adsrt.lib.RecordNotFoundException;
import br.com.telescope.adsrt.lib.SwingRuntime;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import solutions.ferpa.ztest.ent.EntClasseModelo;
import solutions.ferpa.ztest.ent.EntModeloHidrometro;
import solutions.ferpa.ztest.ent.EntUsuarios;
import solutions.ferpa.ztest.ent.EntVazaoPrefixoSerie;

/**
 *
 * @author sandro
 */
public class tempCarga {

    private StringBuilder msgErro;
    
    public void carga(SwingRuntime ctx, String urlArq, String delimitador) {
        msgErro = new StringBuilder();
        StringBuilder completarDescricao = new StringBuilder();
        try {        
            EntModeloHidrometro modelo = new EntModeloHidrometro(ctx);

            EntClasseModelo classeHorizontal = null;
            EntClasseModelo classeVertical = null;
            EntClasseModelo razaoHorizontal = null;
            EntClasseModelo razaoVertical = null;
            EntVazaoPrefixoSerie vazaoPrefixo = null;
            
            File arquivo = new File(urlArq);
            BufferedReader dados = new BufferedReader(new FileReader(arquivo));

            String registro;
            int linha = 0;

            PreparedStatement ps = null;
            ResultSet rs = null;
            try {
                while ((registro = dados.readLine()) != null) {
                    linha++;

                    // Se linha vazia (e/ou o arquivo tem cabeçalho), ignora linha
                    if ((registro == null || registro.length() < 5) || (linha == 0) || (registro.startsWith("Código Produto"))) {
                        // ignora linha (p.ex, primeira linha, se vazia...)
                    } else {
                        if (registro.substring(registro.length()-1).equals(delimitador)) {
                            registro = registro.substring(0, registro.length()-1);
                        }
                        String[] campos = registro.split(delimitador);

                        if (campos.length > 13) {
                            int idx = 0;
                            /*
                            Código Produto, 	        1	Código Produto
                            Descrição Produto,	        2	Descrição Produto
                            Descrição Detalhada,	3	Descrição Detalhada
                            Vazão Nominal (Qn) L,	4	Vazão Nominal (Qn) L
                            Prefixo Vazão,	        5	Prefixo Vazão
                            Vazão Permanente (Q3),	6	Vazão Permanente (Q3)
                            Diâmetro Nominal (DN) mm,	7	Diâmetro Nominal (DN) mm
                            Classe MetrológicaH horizontal,	8	Classe MetrológicaH horizontal
                            Classe MetrológicaVertical,	9	Classe MetrológicaVertical
                            Razão Horizontal,	       10	Razão Horizontal
                            Razão Vertical,	       11	Razão Vertical
                            Comprimento,	       12	Comprimento
                            Portaria de Aprovação,     13	Portaria de Aprovação
                            Marca,	               14	Marca
                            Fator K	               15	Fator K
                            */

                            String codigo_produto = campos[idx++];
                            String descricao_produto = campos[idx++];
                            String descricao_detalhada = campos[idx++];
                            descricao_detalhada = descricao_detalhada.replace("\\#", "\n");
                            String vazao_nominal = campos[idx++];
                            String prefixo_vazao = campos[idx++];
                            prefixo_vazao = (prefixo_vazao == null || prefixo_vazao.isEmpty() ? "?" : prefixo_vazao);  // atribui valor inválido porque é um campo obrigatório...
                            String vazao_permanente = campos[idx++];
                            String diametro_nominal = campos[idx++];
                            String classe_metrologica_horizontal = campos[idx++];
                            if (AdsUtil.getChars(classe_metrologica_horizontal, "ABCD").length() < 1) {
                                classe_metrologica_horizontal = "A";
                                completarDescricao.append("\n").append("*** Atribuído a classe A pois este campos estava vazio ou com valor inválido na planilha enviada pela Zenner...");
                            }
                            String classe_metrologica_vertical = campos[idx++];
                            if (AdsUtil.getChars(classe_metrologica_vertical, "ABCD").length() < 1) {
                                classe_metrologica_vertical = null;
                                completarDescricao.append("\n").append("*** Atribuído NULL para classe metrológica vertical pois este campos estava vazio ou com valor inválido na planilha enviada pela Zenner...");
                            }
                            String razao_horizontal = campos[idx++];
                            String razao_vertical = campos[idx++];
                            String comprimento = campos[idx++];
                            String portaria_aprovacao = campos[idx++];
                            String marca = campos[idx++];
                            String fator_k = (campos.length > 14 ? campos[idx++] : null);
                            
                            /*
                            --> classe_modelo
                            ID	        *	PK_SEQUENCE	
                            DESCRICAO		TEXT_LONG(128)
                            CODIGO	*	UPPER(32)   Código de identificação da classe de modelo de hidrômetro (p.ex, A, B, C...).
                            RAZAO1		DOUBLE	
                            RAZAO2		DOUBLE	
                            RAZAO3		DOUBLE	
                            RAZAO4		DOUBLE	
                            RAZAO5		DOUBLE	
                            RAZAO6		DOUBLE	
                            RAZAO7		DOUBLE	
                            RAZAO8		DOUBLE
                            RAZAO9		DOUBLE
                            RAZAO10             DOUBLE
                            */
                            classeHorizontal = new EntClasseModelo(ctx);
                            classeVertical = new EntClasseModelo(ctx);
                            razaoHorizontal = new EntClasseModelo(ctx);
                            razaoVertical = new EntClasseModelo(ctx);
                            vazaoPrefixo = new EntVazaoPrefixoSerie(ctx);
                            try {
                                if (classe_metrologica_horizontal == null || classe_metrologica_horizontal.isEmpty()) {
                                    classe_metrologica_horizontal = "A";  // atribuído A
                                    completarDescricao.append("\n").append("*** Atribuído a classe A pois este campos estava vazio na planilha enviada pela Zenner...");
                                }
                                classeHorizontal.findByCodigo(classe_metrologica_horizontal);
                            } catch (RecordNotFoundException e) {
                                classeHorizontal.setCodigo(classe_metrologica_horizontal);
                                classeHorizontal.setDescricao("Classe inserida automaticamenta - rotina de carga com base na planilha enviada pela Zenner");
                                classeHorizontal.ins();
                            }

                            classeVertical = new EntClasseModelo(ctx);
                            if (classe_metrologica_vertical == null || classe_metrologica_vertical.isEmpty()) {
                                // pula
                            } else {
                                try {
                                    classeVertical.findByCodigo(classe_metrologica_vertical);
                                } catch (RecordNotFoundException e) {
                                    classeVertical.setCodigo(classe_metrologica_vertical);
                                    classeVertical.setDescricao("Classe inserida automaticamenta - rotina de carga com base na planilha enviada pela Zenner");
                                    classeVertical.ins();
                                }
                            }

                            razaoHorizontal = new EntClasseModelo(ctx);
                            if (razao_horizontal == null || razao_horizontal.isEmpty()) {
                                // pula
                            } else {
                                DomDouble valorRazaoPlanilha = new DomDouble();
                                valorRazaoPlanilha.setValue(valorRazaoPlanilha);
                                razaoHorizontal.filterBy()
                                        .equal(razaoHorizontal.getRazao1(), valorRazaoPlanilha.getValue());
                                if (razaoHorizontal.next()) {
                                    // ok
                                } else {
                                    completarDescricao.append("\n").append("*** Razão informada na planilha enviada pela Zenner não encontrada na lista de classes registradas");
                                }
                            }
                            
                            razaoVertical = new EntClasseModelo(ctx);
                            if (razao_vertical == null || razao_vertical.isEmpty()) {
                                // pula
                            } else {
                                DomDouble valorRazaoPlanilha = new DomDouble();
                                valorRazaoPlanilha.setValue(razaoVertical);
                                razaoVertical.filterBy()
                                        .equal(razaoVertical.getRazao1(), valorRazaoPlanilha.getValue());
                                if (razaoVertical.next()) {
                                    // ok
                                } else {
                                    completarDescricao.append("\n").append("*** Razão informada na planilha enviada pela Zenner não encontrada na lista de classes registradas");
                                }
                            }

                            /*
                            --> vazao_prefixo_serie
                            ID	                        *	PK_SEQUENCE	
                            VAZAO_NOMINAL	        *	DOUBLE	P.ex: 0,75 m3/h  ,1,5 m3/h ,10 m3/h
                            PREFIXO_NUMERO_SERIE	*	UPPER	Prefixo para número de série:
                            ANO_REFERENCIA_SEQUENCIA	*	INTEGER	Ano referência (próxima sequência):
                            PROXIMA_SEQUENCIA_PRODUTO	*	INTEGER	Próxima sequência produto:
                            */                    
                            vazaoPrefixo = new EntVazaoPrefixoSerie(ctx);
                            DomDouble vazaoNominalPlanilha = new DomDouble();
                            if (vazao_nominal == null || vazao_nominal.isEmpty()) {
                                vazaoNominalPlanilha.setValue(vazao_permanente);
                            } else {
                                vazaoNominalPlanilha.setValue(vazao_nominal);
                            }
                            try {
                                vazaoPrefixo.findByVazaoNominal(vazaoNominalPlanilha.getValue().doubleValue());
                            } catch (RecordNotFoundException ex1) {
                                vazaoPrefixo.setVazaoNominal(vazaoNominalPlanilha.getValue().doubleValue());
                                vazaoPrefixo.setPrefixoNumeroSerie(prefixo_vazao);
                                vazaoPrefixo.setAnoReferenciaSequencia(2015);
                                vazaoPrefixo.setProximaSequenciaProduto(1);
                                vazaoPrefixo.ins();
                            } 

                            /*
                            --> modelo
                            ID	                        *	PK_SEQUENCE	
                            CODIGO	                *	UPPER(20)
                            DESCRICAO	                *	TEXT(128)
                            DIAMETRO_NOMINAL	        *	INTEGER	
                            CLASSE_HORIZONTAL_ID	*	ID      fk ZTEST.CLASSE_MODELO
                            CLASSE_VERTICAL_ID		        ID	fk ZTEST.CLASSE_MODELO
                            MARCA	                *	UPPER(40)	
                            FATOR_K		                DOUBLE	
                            PORTARIA_APROVACAO		        TEXT	
                            COMPRIMENTO	                *	INTEGER	
                            VAZAO_PREFIXO_SERIE_ID	*	ID	fk  ZTEST.VAZAO_PREFIXO_SERIE
                            DESCRICAO_DETALHADA		        TEXT_LONG(512)	
                            RAZAO_HORIZONTAL_ID		        ID	fk  ZTEST.CLASSE_MODELO
                            RAZAO_VERTICAL_ID		        ID	fk  ZTEST.CLASSE_MODELO
                            VAZAO_PERMANENTE_ID	        *	ID	fk  ZTEST.VAZAO_PREFIXO_SERIE
                            */
                            modelo = new EntModeloHidrometro(ctx);
                            try {
                                modelo.findByDescricao(descricao_produto);
                            } catch (RecordNotFoundException ex2) {
                                modelo.setCodigo(codigo_produto);
                                modelo.setDescricao(descricao_produto);
                                modelo.setDescricaoDetalhada(descricao_detalhada
                                        + "\n"
                                        + completarDescricao.toString());
                                completarDescricao.setLength(0);
                                modelo.setDiametroNominal(diametro_nominal);
                                modelo.setClasseHorizontalId(classeHorizontal.valueOfId());
                                if (classeVertical.getId().isNotNull()) {
                                    modelo.setClasseVerticalId(classeVertical.valueOfId());
                                }
                                modelo.setMarca(marca);
                                if (fator_k == null || fator_k.isEmpty()) {
                                    // pula
                                } else {
                                    modelo.setFatorK(fator_k);
                                }
                                modelo.setPortariaAprovacao(portaria_aprovacao);
                                if (comprimento == null || comprimento.isEmpty()) {
                                    // pula
                                } else {
                                    modelo.setComprimento(comprimento);
                                }
                                modelo.setVazaoPrefixoSerieId(vazaoPrefixo.valueOfId().longValue());
                                if (razaoHorizontal.getId().isNotNull()) {
                                    modelo.setRazaoHorizontalId(razaoHorizontal.valueOfId());
                                }
                                if (razaoVertical.getId().isNotNull()) {
                                    modelo.setRazaoVerticalId(razaoVertical.valueOfId());
                                }
                                modelo.setVazaoPermanenteId(vazaoPrefixo.valueOfId());  // atribuido igual ao campo VAZAO_PREFIXO_SERIE_ID 
                                modelo.ins();
                            }
                            
                            System.out.println(linha + "."
                                    + " #" + codigo_produto 
                                    + " #" + descricao_produto
                                    );
                        } else {
                            System.out.println(linha + "."
                                    + " #" + registro
                                    );
                        }

                        /*
                        if (msgErro.length() > 0) {
                            ctx.p(msgErro.toString());
                        }

                        ps = conexaoBase.prepareStatement(
                                "insert into produto"
                                + " ( id ,codigo_produto ,descricao_produto ,setor ,grupo ,classe ,codigo_subclasse ,subclasse ,comprador ,situacao ,codigo_fornecedor ,fornecedor )"
                                + " values"
                                + " ( nextval('pk_colecao_dados')"
                                + " ,? ,? ,? ,? ,? ,? ,? ,? ,? ,? ,? )"
                                );

                        //System.out.println("ps: " + ps.toString());
                        ps.setInt(1, Integer.parseInt(codigo_produto));
                        ps.setString(2, descricao_produto);
                        ps.setString(3, setor);
                        ps.setString(4, grupo);
                        ps.setString(5, classe);
                        ps.setString(6, codigo_subclasse);
                        ps.setString(7, subclasse);
                        ps.setString(8, comprador);
                        ps.setString(9, situacao);
                        ps.setString(10, codigo_fornecedor);
                        ps.setString(11, fornecedor);

                        int sqlIns = ps.executeUpdate();
                        */
                    }
                    if (linha > 9999) {
                        System.out.println("... interrompido na linha " + linha + "\n" + registro);
                        break;
                    }
                }
            } catch (Exception ex) {
                ex.printStackTrace();
                System.out.println("Erro: " + ex.toString());
                // ?
            } finally  {
                try {
                    ps.close();
                    rs.close();
                } catch (Exception ignore) {
                    // ignore
                }
            }
            dados.close();
        } catch (Exception ex1) {
            // ignore
        }
    }

    
    public static void main(String[] args) {
        String pUrlArq = (args == null || args.length == 0 || args[0].isEmpty() ? "C:/projs/ZTEST/sql/Lista de Produtos Ensaio 2015.csv" : args[0]);
        String pDelimitador = (args == null || args.length == 0 || args[1].isEmpty() ? "\t" : args[1]); 
        String arquivoConfiguracao = (args == null || args.length == 0 || args[1].isEmpty() ? "C:/Users/sandro/apps/ZTEST/config.cfg" : args[1]); 

        tempCarga t = new tempCarga();
        try {
            SwingRuntime pCtx = new SwingRuntime(arquivoConfiguracao);
            Connection connection;
            try {
                Class.forName(pCtx.getInitParameter("CONFIG.DB.DEFAULT.DRIVER"));
                connection = DriverManager.getConnection(
                        pCtx.getInitParameter("CONFIG.DB.DEFAULT.URL"), 
                        pCtx.getInitParameter("CONFIG.DB.DEFAULT.USER"), 
                        pCtx.getInitParameter("CONFIG.DB.DEFAULT.PASSWORD"));
                pCtx.setConnection("default", connection);
            } catch (Exception e) {
                throw new AdsException(e);
            }
            EntUsuarios user = new EntUsuarios(pCtx);
            user.filterBy()
                    .equal(user.getSuperUsuario(), "S");
            user.next();  // pega o primeiro super usuário selecionada
            pCtx.getSession().login(user.getUser());

            t.carga(pCtx, pUrlArq, pDelimitador);
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("Erro: " + e.toString());
        }
        
    }
    
}
